package com.example.shopspring.config;

import com.example.shopspring.common.ResultData;
import com.example.shopspring.common.ReturnCode;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.sql.SQLException;

@RestControllerAdvice
public class GlobExceptionHandler {
    @ExceptionHandler(Exception.class)
    public ResultData exception(Exception e) {
        Throwable sourceCause = this.getSourceCause(e, e.getCause());
        if (null != sourceCause) {
            if ((sourceCause instanceof SQLException)) {
                return ResultData.error(ReturnCode.SYSTEM_ERROR.getCode(), "执行后台sql语句出现异常！");
            }
            if ((sourceCause instanceof NullPointerException)) {
                return ResultData.error(ReturnCode.SYSTEM_ERROR.getCode(), "空指针异常！");
            }
        }
        return ResultData.error(ReturnCode.SYSTEM_ERROR);
    }


    //直接监听BindException类就行MethodArgumentNotValidException都是继承得BindException类
    @ExceptionHandler(BindException.class)
    public ResultData methodArgumentNotValidException(BindException ex) {
        StringBuffer sb = new StringBuffer();
        //遍历所有的错误结果
        for (ObjectError allError : ex.getAllErrors()) {
            sb.append(allError.getDefaultMessage() + "; ");
        }
        return ResultData.error(ReturnCode.PARAM_ERROR.getCode(), sb.toString());
    }

    /**
     * 取得当前异常最初引发来源方
     */
    private Throwable getSourceCause(Exception e, Throwable ex) {

        if ((e instanceof SQLException)) {
            return e;
        }
        if ((e instanceof NullPointerException)) {
            return e;
        }

        if (ex == null)
            return null;

        if (ex.getCause() == null)
            return ex;
        else
            return getSourceCause(e, ex.getCause());

    }

}
